package com.irdstudio.efp.esb.api.rest.yed.loanManage;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.constant.ESBConstant;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.efp.basic.framework.mq.client.producer.MQProducerMessageClient;
import com.irdstudio.efp.basic.framework.mq.constant.TagEnums;
import com.irdstudio.efp.basic.framework.mq.constant.TopicEnums;
import com.irdstudio.efp.console.service.facade.PrdInfoService;
import com.irdstudio.efp.console.service.facade.PubSysInfoService;
import com.irdstudio.efp.console.service.vo.PrdInfoVO;
import com.irdstudio.efp.edoc.service.bo.UpLoadFileVO;
import com.irdstudio.efp.edoc.service.facade.UpLoadFileService;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.api.common.GroupeInterface;
import com.irdstudio.efp.esb.api.rest.EsbController;
import com.irdstudio.efp.esb.api.rest.yed.req.ReqSettleCertSignCfcaBean;
import com.irdstudio.efp.esb.api.rest.yed.resp.RespSettleCertSignCfcaBean;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.constant.MsLoanConstant;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.loan.service.facade.AccLoanService;
import com.irdstudio.efp.loan.service.vo.AccLoanVO;
import com.irdstudio.efp.nls.service.facade.NlsApplyInfoService;
import com.irdstudio.efp.nls.service.vo.NlsApplyInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 优e贷 结清证明申请接口 渠道-》网贷-》cfca签章-》影像
 * @author liangcongming :2020/8/10 18:12
 * @version 0.1
 * @date 2020/8/10 18:12
 * @since 2020/8/10 18:12
 */
@RestController
@RequestMapping("/esb")
public class YedSettleCertSignCfcaController implements EsbController {
    private static Logger logger = LoggerFactory.getLogger(YedSettleCertSignCfcaController.class);

    @Autowired
    @Qualifier("prdInfoService")
    private PrdInfoService prdInfoService;

    @Autowired
    @Qualifier("nlsApplyInfoService")
    private NlsApplyInfoService nlsApplyInfoService;// 网贷申请基本信息

    @Autowired
    @Qualifier("accLoanService")
    private AccLoanService accLoanService;

    @Autowired
    @Qualifier("pubSysInfoService")
    private PubSysInfoService pubSysInfoService;

    @Autowired
    @Qualifier("producerService")
    private MQProducerMessageClient producerService;

    @Autowired
    @Qualifier("upLoadFileService")
    private UpLoadFileService upLoadFileService;

    /**
     * 获取ESB请求对象，校验 ESB请求系统头和请求应用头对象
     *
     * @param request 请求对象集合
     * @return
     */
    @ModelAttribute("esbReqServiceBean")
    public EsbReqServiceBean getReqEsbHeadBean(HttpServletRequest request) {
        logger.info("校验 ESB请求系统头和请求应用头对象!");
        EsbReqServiceBean esbReqServiceBean = (EsbReqServiceBean) request.getAttribute("esbReqServiceBean");
        return esbReqServiceBean;
    }

    /**
     * 获取ESB请求对象，校验 ESB请求体对象
     *
     * @param request 请求对象集合
     * @return
     */
    @ModelAttribute("reqSettleCertSignCfcaBean")
    public ReqSettleCertSignCfcaBean getReqEsbBodyBean(HttpServletRequest request) {
        logger.info("校验 ESB请求体对象！");
        String esbReqBody = (String) request.getAttribute("esbReqBody");
        return JSONObject.parseObject(esbReqBody, ReqSettleCertSignCfcaBean.class);
    }

    @PostMapping("/SERVICE_30220027_01")
    public EsbRespServiceBean doRecv(@Validated @ModelAttribute("esbReqServiceBean") EsbReqServiceBean esbReqServiceBean, BindingResult br1,
                                     @Validated({GroupeInterface.yed.class}) @ModelAttribute("reqSettleCertSignCfcaBean") ReqSettleCertSignCfcaBean reqSettleCertSignCfcaBean, BindingResult br2, Exception exception){
        String glblSrlNo = esbReqServiceBean.getSysHead().getGlblSrlNo();
        logger.info("优e贷结清证明申请接口开始,全局流水号为：[{}]", glblSrlNo);
        String setlSeq = reqSettleCertSignCfcaBean.getSetlSeq();
        logger.info("优e贷结清证明申请接口开始,请求申请流水号为：[{}]", setlSeq);

        try {
            // 参数校验
            validateBean(esbReqServiceBean, br1, reqSettleCertSignCfcaBean, br2, exception, logger);
            // 设置系统头对象
            setSysHeadFieldThreadLocal(esbReqServiceBean);

            if (Objects.nonNull(exception)) {
                throw exception;
            }

            //【第一步】判断产品
            PrdInfoVO prdParam = new PrdInfoVO();
            prdParam.setPrdId(reqSettleCertSignCfcaBean.getPrdid());
            PrdInfoVO prdInfoVO = prdInfoService.queryByPk(prdParam);

            if (Objects.isNull(prdInfoVO)) {
                throw new BizException(EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(),"产品ID错误，请检查！");
            }

            //【第二步】根据借据号查借据信息是否存在并且已结清
            AccLoanVO accLoanVO = new AccLoanVO();
            accLoanVO.setBillNo(reqSettleCertSignCfcaBean.getLoanNo());
            AccLoanVO quyAccLoanVO = accLoanService.queryByPk(accLoanVO);
            if (Objects.isNull(quyAccLoanVO)) {
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "根据借据号未能找到借据信息！");
            }
            // 参见字典表 STD_ZB_ACC_STATUS
            if (!("11".equals(quyAccLoanVO.getAccountStatus()) || "13".equals(quyAccLoanVO.getAccountStatus()) || "4".equals(quyAccLoanVO.getAccountStatus()))) {
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "请明天再来申请，谢谢！");
            }

            // 【第三步】 根据用信号查用信信息
            NlsApplyInfoVO inNlsApplyInfoVO = new NlsApplyInfoVO();
            inNlsApplyInfoVO.setApplySeq(quyAccLoanVO.getApplySeq());
            NlsApplyInfoVO queryNlsApplyInfoVO = nlsApplyInfoService.queryByPk(inNlsApplyInfoVO);

            // 【第四步】 校验参数是否与库一致
            checkNlsApplyInfo(queryNlsApplyInfoVO,reqSettleCertSignCfcaBean);

            // 【第五步】根据流水号查up_load_file表，已成功上送影像的则拒绝
            UpLoadFileVO upLoadFileVO = new UpLoadFileVO();
            upLoadFileVO.setApplySeq(queryNlsApplyInfoVO.getApplySeq());
            upLoadFileVO.setImageType("Y04");//优e贷结清证明文件 影像类型
            UpLoadFileVO queryUpLoadFileVO = upLoadFileService.queryUploadFileByApplySeqAndImageType(upLoadFileVO);

            if(validateUpLoadFileVO(queryUpLoadFileVO,queryNlsApplyInfoVO)){
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(),"根据用信号和影像类型已查到成功上传的影像信息！无需重复申请！");
            }

            // 【第六步】查询营业日
            String openday = pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001);
            if (StringUtils.isEmpty(openday)) {
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "尊敬的客户您好，由于系统异常本次签订合同失败，请您稍后再试");
            }

            // 6.异步处理
            producerService.sendMsg(new Message(TopicEnums.YED_SETTLE_CERT_QUEUE_TASK_TOPIC.getTopicId(), TagEnums.YED_SETTLE_CERT_TAG_QUEUE_TASK.getTagId(), quyAccLoanVO.getApplySeq(),
                    JSON.toJSONString(quyAccLoanVO).getBytes("UTF-8")));

            logger.info("优e贷结清证明文件申请成功,全局流水号为：[{}]", glblSrlNo);
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                    JSON.toJSONString(buildRespSettleCertSignCfcaBean(ESBConstant.SUCCESS, "申请成功")), //
                    EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), //
                    EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), //
                    "申请成功");

        } catch (BizException be) {
            logger.error("***********优e贷结清证明文件申请异常!", be);
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                    JSON.toJSONString(buildRespSettleCertSignCfcaBean(be.getErrorCode(), be.getMessage())), //
                    EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), //
                    EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(), //
                    be.getMessage());
        } catch (Exception e) {
            logger.error("***********优e贷结清证明文件申请异常!", e);
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                    JSON.toJSONString(buildRespSettleCertSignCfcaBean(EsbBizEnums.RetCodeEnum.JKYDCSJYBTG.getVALUE(), e.getMessage())), //
                    EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), //
                    EsbBizEnums.RetCodeEnum.JKYDCSJYBTG.getVALUE(), //
                    e.getMessage());
        } finally {
            logger.info("优e贷结清证明文件申请结束,全局流水号为：[{}]", glblSrlNo);
        }

    }

    private RespSettleCertSignCfcaBean buildRespSettleCertSignCfcaBean(String retCode, String retMsg) {
        RespSettleCertSignCfcaBean bean = new RespSettleCertSignCfcaBean();
        bean.setRetCd(retCode);
        bean.setRetMsg(retMsg);
        return bean;
    }

    /**
     * 校验申请日期，上传状态是否正确
     * @param queryUpLoadFileVO
     * @param queryNlsApplyInfoVO
     * @return
     */
    private boolean validateUpLoadFileVO(UpLoadFileVO queryUpLoadFileVO,NlsApplyInfoVO queryNlsApplyInfoVO){
        Objects.requireNonNull(queryUpLoadFileVO);
        Boolean flag = true;
        
        if(!"SUCCESS".equals(queryUpLoadFileVO.getState())){
            return false;
        }
        if(Objects.isNull(queryUpLoadFileVO.getBatch())){
            return false;
        }
        return flag;
    }

    private void checkNlsApplyInfo(NlsApplyInfoVO queryNlsApplyInfoVO,ReqSettleCertSignCfcaBean reqSettleCertSignCfcaBean) throws BizException{
        if(Objects.isNull(queryNlsApplyInfoVO)){
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(),"根据用信号未能找到用信申请信息，请检查！");
        }
        if(!reqSettleCertSignCfcaBean.getCerttype().equals(queryNlsApplyInfoVO.getCertType())){
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(),"借据证件类型不匹配，请检查！");
        }
        if(!reqSettleCertSignCfcaBean.getCertcode().equals(queryNlsApplyInfoVO.getCertCode())){
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(),"借据证件号不匹配，请检查！");
        }
        if(!reqSettleCertSignCfcaBean.getPrdid().equals(queryNlsApplyInfoVO.getPrdId())){
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(),"产品ID不匹配，请检查！");
        }

    }

}
